import 'package:flutter/cupertino.dart';
import 'package:flutter/gestures.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:super_tool_server/component/clickable/clickable_widget.dart';
import 'package:super_tool_server/component/input_text/hint_text.dart';

///输入框
class EditTextField extends StatefulWidget {
  EditTextField({
    required this.controller,
    required this.focusNode,
    required this.textStyle,
    this.maxLines = 1,
    this.maxLength,
    this.cursorColor,
    TextInputType? keyboardType,
    this.obscureText = false,
    this.enabled = true,
    this.isShowDeleteButton = false,
    this.enableInteractiveSelection = true,
    this.autoFocus = false,
    this.onTap,
    this.onChanged,
    this.onEditingComplete,
    this.onSubmitted,
    this.onTapDelete,
    this.onHover,
    this.inputFormatters,
    this.maxLengthEnforcement,
    this.hintMaxLines,
    this.hintStyle,
    this.hintText,
    Key? key,
  })  : keyboardType = keyboardType ?? (maxLines == 1 ? TextInputType.text : TextInputType.multiline),
        super(key: key);

  final TextEditingController? controller;
  final FocusNode? focusNode;
  final TextStyle textStyle;

  /// 最大行数
  final int maxLines;

  ///最大长度
  final int? maxLength;

  /// 键盘类型
  final TextInputType keyboardType;

  ///光标颜色
  final Color? cursorColor;

  /// 是否隐藏输入的信息 如 密码
  final bool obscureText;

  ///是否可输入
  final bool enabled;

  ///是否显示删除button
  final bool isShowDeleteButton;

  ///是否显示select 提示
  final bool enableInteractiveSelection;

  ///点击
  final GestureTapCallback? onTap;

  ///输入中
  final ValueChanged<String>? onChanged;

  ///编辑完成
  final VoidCallback? onEditingComplete;

  ///点击删除
  final VoidCallback? onTapDelete;

  ///提交
  final ValueChanged<String>? onSubmitted;

  /// hover 状态回调
  final ValueChanged<bool>? onHover;

  ///自动获取焦点
  final bool autoFocus;

  ///输入格式
  final List<TextInputFormatter>? inputFormatters;

  ///最大长度样式
  final MaxLengthEnforcement? maxLengthEnforcement;

  ///提示文字样式
  final String? hintText;

  ///提示文字样式
  final TextStyle? hintStyle;

  ///提示文字最多行数
  final int? hintMaxLines;

  @override
  _EditTextFieldState createState() => _EditTextFieldState();
}

class _EditTextFieldState extends State<EditTextField> implements TextSelectionGestureDetectorBuilderDelegate {
  bool _isHovering = false;
  bool _forcePressEnabled = false;
  FocusNode? _focusNode;

  FocusNode get _effectiveFocusNode => widget.focusNode ?? (_focusNode ??= FocusNode());
  late _InputTextFieldSelectionGestureDetectorBuilder _selectionGestureDetectorBuilder;
  bool _showSelectionHandles = false;

  bool _isTextEmpty = false;
  bool _hasDeleteButton = false;

  TextEditingController? _controller;
  late VoidCallback _textOnChange;

  TextEditingController get _effectiveController => widget.controller ?? (_controller ??= TextEditingController());

  MaxLengthEnforcement get _effectiveMaxLengthEnforcement =>
      widget.maxLengthEnforcement ??
      LengthLimitingTextInputFormatter.getDefaultMaxLengthEnforcement(Theme.of(context).platform);

  @override
  void initState() {
    _selectionGestureDetectorBuilder = _InputTextFieldSelectionGestureDetectorBuilder(state: this);
    _isTextEmpty = _effectiveController.text.isEmpty;

    _textOnChange = () {
      if (_effectiveController.text.isEmpty != _isTextEmpty) {
        _isTextEmpty = _effectiveController.text.isEmpty;
        if (widget.isShowDeleteButton) {
          _hasDeleteButton = _effectiveController.text.isNotEmpty;
        }
        setState(() {});
      }
    };
    if (widget.controller != null) {
      _hasDeleteButton = widget.controller!.text.isNotEmpty;
    }
    _effectiveController.addListener(_textOnChange);
    super.initState();
  }

  @override
  void dispose() {
    _effectiveController.removeListener(_textOnChange);
    _controller?.dispose();
    _focusNode?.dispose();

    super.dispose();
  }

  void _handleHover(bool hovering) {
    if (hovering != _isHovering) {
      setState(() {
        _isHovering = hovering;
      });
      if (widget.onHover != null) {
        widget.onHover!(_isHovering);
      }
    }
  }

  bool _shouldShowSelectionHandles(SelectionChangedCause? cause) {
    if (!_selectionGestureDetectorBuilder.shouldShowSelectionToolbar) {
      return false;
    }

    if (cause == SelectionChangedCause.keyboard) {
      return false;
    }

    if (_effectiveController.selection.isCollapsed) {
      return false;
    }

    if (!widget.enabled) {
      return false;
    }

    if (cause == SelectionChangedCause.longPress) {
      return true;
    }

    if (_effectiveController.text.isNotEmpty) {
      return true;
    }

    return false;
  }

  @override
  final GlobalKey<EditableTextState> editableTextKey = GlobalKey<EditableTextState>();

  @override
  bool get forcePressEnabled => _forcePressEnabled;

  ///是否显示slelect
  @override
  bool get selectionEnabled => widget.enableInteractiveSelection;

  EditableTextState? get _editableText => editableTextKey.currentState;

  void _handleSelectionChanged(TextSelection selection, SelectionChangedCause? cause) {
    final bool willShowSelectionHandles = _shouldShowSelectionHandles(cause);
    if (willShowSelectionHandles != _showSelectionHandles) {
      setState(() {
        _showSelectionHandles = willShowSelectionHandles;
      });
    }

    switch (Theme.of(context).platform) {
      case TargetPlatform.iOS:
      case TargetPlatform.macOS:
        if (cause == SelectionChangedCause.longPress) {
          _editableText?.bringIntoView(selection.base);
        }
        return;
      case TargetPlatform.android:
      case TargetPlatform.fuchsia:
      case TargetPlatform.linux:
      case TargetPlatform.windows:
      // Do nothing.
    }
  }

  void _requestKeyboard() {
    _editableText?.requestKeyboard();
  }

  @override
  Widget build(BuildContext context) {
    final MouseCursor effectiveMouseCursor = MaterialStateProperty.resolveAs<MouseCursor>(
      MaterialStateMouseCursor.textable,
      <MaterialState>{
        if (!widget.enabled) MaterialState.disabled,
        if (_isHovering) MaterialState.hovered,
        if (_effectiveFocusNode.hasFocus) MaterialState.focused,
        // if (_hasError) MaterialState.error,
      },
    );

    final ThemeData theme = Theme.of(context);

    TextSelectionControls? textSelectionControls;
    late bool paintCursorAboveText;
    Color? cursorColor = widget.cursorColor;
    Color? selectionColor;
    Radius? cursorRadius;

    Color? autoCorrectionTextRectColor;
    switch (theme.platform) {
      case TargetPlatform.iOS:
        final CupertinoThemeData cupertinoTheme = CupertinoTheme.of(context);
        _forcePressEnabled = true;
        textSelectionControls ??= cupertinoTextSelectionControls;
        paintCursorAboveText = true;
        cursorColor ??= cupertinoTheme.primaryColor;
        selectionColor = cupertinoTheme.primaryColor.withOpacity(0.40);
        cursorRadius ??= const Radius.circular(2.0);

        ///iOS 需要，否则是黑色的
        autoCorrectionTextRectColor = selectionColor;
        break;

      case TargetPlatform.macOS:
        final CupertinoThemeData cupertinoTheme = CupertinoTheme.of(context);
        _forcePressEnabled = false;
        textSelectionControls ??= cupertinoDesktopTextSelectionControls;
        paintCursorAboveText = true;
        cursorColor ??= widget.cursorColor ?? cupertinoTheme.primaryColor;
        selectionColor = cupertinoTheme.primaryColor.withOpacity(0.40);
        break;

      case TargetPlatform.android:
      case TargetPlatform.fuchsia:
        _forcePressEnabled = false;
        textSelectionControls ??= materialTextSelectionControls;
        paintCursorAboveText = false;
        cursorColor ??= widget.cursorColor ?? theme.colorScheme.primary;
        selectionColor = theme.colorScheme.primary.withOpacity(0.40);
        break;

      case TargetPlatform.linux:
      case TargetPlatform.windows:
        _forcePressEnabled = false;
        textSelectionControls ??= desktopTextSelectionControls;
        paintCursorAboveText = false;
        // cursorOpacityAnimates = false;
        cursorColor ??= widget.cursorColor ?? theme.colorScheme.primary;
        selectionColor = theme.colorScheme.primary.withOpacity(0.40);
        break;
    }

    final List<TextInputFormatter> formatters = <TextInputFormatter>[
      ...?widget.inputFormatters,
      if (widget.maxLength != null)
        LengthLimitingTextInputFormatter(
          widget.maxLength,
          maxLengthEnforcement: _effectiveMaxLengthEnforcement,
        ),
    ];
    Widget child = Row(
      mainAxisAlignment: MainAxisAlignment.center,
      children: [
        Expanded(
            child: _selectionGestureDetectorBuilder.buildGestureDetector(
          behavior: HitTestBehavior.translucent,
          child: RepaintBoundary(
            child: MouseRegion(
              cursor: effectiveMouseCursor,
              onEnter: (PointerEnterEvent event) => _handleHover(true),
              onExit: (PointerExitEvent event) => _handleHover(false),
              child: IgnorePointer(
                ignoring: widget.enabled,
                child: EditableText(
                  key: editableTextKey,
                  controller: _effectiveController,
                  focusNode: _effectiveFocusNode,
                  style: widget.textStyle,
                  cursorColor: cursorColor,
                  backgroundCursorColor: Colors.transparent,
                  obscureText: widget.obscureText,
                  selectionColor: selectionColor,
                  paintCursorAboveText: paintCursorAboveText,
                  selectionControls: selectionEnabled ? textSelectionControls : null,
                  showSelectionHandles: _showSelectionHandles,
                  onSelectionChanged: _handleSelectionChanged,
                  onChanged: widget.onChanged,
                  onEditingComplete: widget.onEditingComplete,
                  onSubmitted: widget.onSubmitted,
                  autofocus: widget.autoFocus,
                  maxLines: widget.maxLines,
                  inputFormatters: formatters,
                  autocorrectionTextRectColor: autoCorrectionTextRectColor,
                  enableInteractiveSelection: widget.enableInteractiveSelection,
                ),
              ),
            ),
          ),
        )),
        if (_hasDeleteButton)
          ClickableWidget(onTap: () {
            if (widget.onTapDelete != null) {
              widget.onTapDelete!();
            }
            _effectiveController.clear();
            widget.onChanged?.call('');
            setState(() {});
          }, builder: (context, _) {
            return Align(
              alignment: Alignment.centerRight,
              child: Icon(
                Icons.close,
                size: 18.0,
              ),
            );
          })
      ],
    );

    if (_hasDeleteButton) {}
    if (widget.hintText != null && widget.hintText!.isNotEmpty) {
      child = HintTextWidget(
        isEmpty: _effectiveController.text.isEmpty,
        hintText: widget.hintText,
        hintStyle: widget.hintStyle,
        hintMaxLines: widget.hintMaxLines,
        child: child,
      );
    }

    // if (kIsWeb) {
    //   ///web的快捷键操作
    //   return Shortcuts(
    //     shortcuts: scrollShortcutOverrides,
    //     child: child,
    //   );
    // }
    return child;
  }
}

class _InputTextFieldSelectionGestureDetectorBuilder extends TextSelectionGestureDetectorBuilder {
  _InputTextFieldSelectionGestureDetectorBuilder({
    required _EditTextFieldState state,
  })  : _state = state,
        super(delegate: state);

  final _EditTextFieldState _state;

  @override
  void onForcePressStart(ForcePressDetails details) {
    super.onForcePressStart(details);
    if (delegate.selectionEnabled && shouldShowSelectionToolbar) {
      editableText.showToolbar();
    }
  }

  @override
  void onForcePressEnd(ForcePressDetails details) {
    // Not required.
  }

  @override
  void onSingleLongTapMoveUpdate(LongPressMoveUpdateDetails details) {
    if (delegate.selectionEnabled) {
      switch (Theme.of(_state.context).platform) {
        case TargetPlatform.iOS:
        case TargetPlatform.macOS:
          renderEditable.selectPositionAt(
            from: details.globalPosition,
            cause: SelectionChangedCause.longPress,
          );
          break;
        case TargetPlatform.android:
        case TargetPlatform.fuchsia:
        case TargetPlatform.linux:
        case TargetPlatform.windows:
          renderEditable.selectWordsInRange(
            from: details.globalPosition - details.offsetFromOrigin,
            to: details.globalPosition,
            cause: SelectionChangedCause.longPress,
          );
          break;
      }
    }
  }

  @override
  // void onSingleTapUp(TapUpDetails details) {
  //   editableText.hideToolbar();
  //   if (delegate.selectionEnabled) {
  //     switch (Theme.of(_state.context).platform) {
  //       case TargetPlatform.iOS:
  //       case TargetPlatform.macOS:
  //         switch (details.kind) {
  //           case PointerDeviceKind.mouse:
  //           case PointerDeviceKind.stylus:
  //           case PointerDeviceKind.invertedStylus:
  //             // Precise devices should place the cursor at a precise position.
  //             renderEditable.selectPosition(cause: SelectionChangedCause.tap);
  //             break;
  //           case PointerDeviceKind.touch:
  //           case PointerDeviceKind.unknown:
  //           case PointerDeviceKind.trackpad:
  //             // On macOS/iOS/iPadOS a touch tap places the cursor at the edge
  //             // of the word.
  //             renderEditable.selectWordEdge(cause: SelectionChangedCause.tap);
  //             break;
  //         }
  //         break;
  //       case TargetPlatform.android:
  //       case TargetPlatform.fuchsia:
  //       case TargetPlatform.linux:
  //       case TargetPlatform.windows:
  //         renderEditable.selectPosition(cause: SelectionChangedCause.tap);
  //         break;
  //     }
  //   }
  //   _state._requestKeyboard();
  //   if (_state.widget.onTap != null) {
  //     _state.widget.onTap!();
  //   }
  // }

  @override
  void onSingleLongTapStart(LongPressStartDetails details) {
    if (delegate.selectionEnabled) {
      switch (Theme.of(_state.context).platform) {
        case TargetPlatform.iOS:
        case TargetPlatform.macOS:
          renderEditable.selectPositionAt(
            from: details.globalPosition,
            cause: SelectionChangedCause.longPress,
          );
          break;
        case TargetPlatform.android:
        case TargetPlatform.fuchsia:
        case TargetPlatform.linux:
        case TargetPlatform.windows:
          renderEditable.selectWord(cause: SelectionChangedCause.longPress);
          Feedback.forLongPress(_state.context);
          break;
      }
    }
  }
}
